package com.example.mqttclient;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.SwitchCompat;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.example.mqttclient.mqtt.MqttService;
import com.example.mqttclient.protocol.AirConditioningMessage;
import com.example.mqttclient.protocol.BoolMessage;
import com.example.mqttclient.protocol.FloatMessage;
import com.example.mqttclient.protocol.IntMessage;
import com.example.mqttclient.utils.NotificationUtils;
import com.example.mqttclient.weather.WeatherFetcher;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.gson.Gson;

import org.eclipse.paho.client.mqttv3.MqttException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

public class DevicesDemoActivity extends AppCompatActivity implements MqttService.MqttEventCallBack,
        CompoundButton.OnCheckedChangeListener, WeatherFetcher.WeatherCallback {

    //语音识别
    private SpeechRecognizer speechRecognizer; // 语音识别器
    private TextToSpeech textToSpeech; // 文本转语音
    private ImageButton voiceBtn; // 语音按钮
    private final int REQUEST_VOICE = 100; // 语音识别请求码
    private SwitchCompat themeSwitch;
    private boolean isDarkTheme = false;


    private TextView connectState, temperatureValue, humidityValue, pmValue, gasValue, doorStatus, carbonFootprintView;
    private EditText airConditioningValue;
    private MqttService.MqttBinder mqttBinder;
    private String TAG = "DevicesDemoActivity";
    private SwitchMaterial parlourLightSwitch, curtain_switch, fan_socket_switch, air_conditioning_switch;
    private Map<String, Integer> subscribeTopics = new HashMap<>();

    // 设备能耗跟踪
    private Map<String, Long> deviceUsageTime = new HashMap<>();
    private Map<String, Double> devicePowerRatings = new HashMap<>();
    private DatabaseHelper dbHelper;
    private Timer dataLoggerTimer;
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mqttBinder = (MqttService.MqttBinder) iBinder;
            mqttBinder.setMqttEventCallBack(DevicesDemoActivity.this);
            if (mqttBinder.isConnected()) {
                connectState.setText("已连接");
                subscribeTopics();
            } else {
                connectState.setText("未连接");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mqttBinder = null;
        }
    };

    private Spinner fanGearSpinner;
    private int currentFanGear = 1; // 默认档位为 1

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_devices_demo);
        startDataLoggingTimer();
        // 初始化 UI 组件
        connectState = findViewById(R.id.dev_connect_state);
        temperatureValue = findViewById(R.id.temperature_value);
        humidityValue = findViewById(R.id.humidity_value);
        pmValue = findViewById(R.id.pm_value);
        gasValue = findViewById(R.id.gas_value);
        doorStatus = findViewById(R.id.door_status);
        carbonFootprintView = findViewById(R.id.carbon_footprint);
        airConditioningValue = findViewById(R.id.air_conditioning_value);

        // 初始化开关控件
        parlourLightSwitch = findViewById(R.id.parlour_light_switch);
        curtain_switch = findViewById(R.id.curtain_switch);
        fan_socket_switch = findViewById(R.id.fan_socket_switch);
        air_conditioning_switch = findViewById(R.id.air_conditioning_switch);

        // 初始化风扇档位选择器
        fanGearSpinner = findViewById(R.id.fan_gear_spinner);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                R.array.fan_gears, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        fanGearSpinner.setAdapter(adapter);
        fanGearSpinner.setSelection(0); // 默认选择第一个档位
        fanGearSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                currentFanGear = position + 1;
                if (fan_socket_switch.isChecked()) {
                    try {
                        mqttBinder.publishMessage("/test/fan1/gear", new Gson().toJson(new IntMessage(currentFanGear)));
                    } catch (MqttException e) {
                        Log.e(TAG, "MQTT publish error", e);
                    }
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                // Do nothing
            }
        });

        // 设置监听器
        parlourLightSwitch.setOnCheckedChangeListener(this);
        curtain_switch.setOnCheckedChangeListener(this);
        fan_socket_switch.setOnCheckedChangeListener(this);
        air_conditioning_switch.setOnCheckedChangeListener(this);

        // 初始化数据库
        dbHelper = new DatabaseHelper(this);

        // 初始化设备功率数据
        devicePowerRatings.put("light", 10.0);
        devicePowerRatings.put("curtain", 20.0);
        devicePowerRatings.put("fan", 50.0);
        devicePowerRatings.put("ac", 1000.0);

        // 添加历史按钮点击事件
        Button historyButton = findViewById(R.id.historyButton);
        historyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 启动历史记录 Activity
                Intent intent = new Intent(DevicesDemoActivity.this, HistoryActivity.class);
                startActivity(intent);
            }
        });

        // 绑定 MQTT 服务
        Intent mqttServiceIntent = new Intent(this, MqttService.class);
        bindService(mqttServiceIntent, connection, Context.BIND_AUTO_CREATE);

        // 设置定时器每分钟更新一次碳排放
        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                updateCarbonFootprint();
            }
        }, 0, 60000);

        new WeatherFetcher(this, this).execute();


        //语音功能
        voiceBtn = findViewById(R.id.voice_control_btn); // 确保此处 ID 正确
        if (voiceBtn != null) { // 添加空指针检查（临时防护）
            voiceBtn.setOnClickListener(this::startVoiceRecognition);
        } else {
            Log.e(TAG, "voiceBtn is null, 请检查布局文件中的 ID 是否正确");
        }
        // 初始化语音识别器
        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
        speechRecognizer.setRecognitionListener(new RecognitionListener() {
            @Override
            public void onResults(Bundle results) {
                ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
                if (matches != null && !matches.isEmpty()) {
                    String command = matches.get(0).toLowerCase();
                    handleVoiceCommand(command);
                    speakText("你说的是：" + command);
                    Log.d(TAG, "识别结果：" + command); // 添加日志确认结果
                } else {
                    Log.d(TAG, "未识别到语音指令");
                }
            }

            // 实现所有抽象方法（空实现）
            @Override
            public void onRmsChanged(float rmsdB) {
                // 麦克风音量变化回调（无需处理）
            }

            @Override
            public void onBufferReceived(byte[] buffer) {
                // 音频缓冲区接收回调（无需处理）
            }

            @Override
            public void onPartialResults(Bundle partialResults) {
                // 部分识别结果回调（无需处理）
            }

            @Override
            public void onEvent(int eventType, Bundle params) {
                // 系统事件回调（无需处理）
            }

            @Override
            public void onReadyForSpeech(Bundle params) {
                // 准备接收语音回调（无需处理）
            }

            @Override
            public void onBeginningOfSpeech() {
                // 开始语音输入回调（无需处理）
            }

            @Override
            public void onEndOfSpeech() {
                // 结束语音输入回调（无需处理）
            }

            @Override
            public void onError(int error) {
                speakText("语音识别失败：" + error);
            }
        });

        // 初始化文本转语音
        textToSpeech = new TextToSpeech(this, status -> {
            if (status == TextToSpeech.SUCCESS) {
                textToSpeech.setLanguage(Locale.CHINESE); // 设置中文
            }
        });

        // 初始化主题切换开关
        themeSwitch = findViewById(R.id.theme_switch);

        // 读取保存的主题状态（首次默认浅色）
        isDarkTheme = getSharedPreferences("ThemePrefs", MODE_PRIVATE)
                .getBoolean("isDarkTheme", false);

        // 设置当前主题
        setThemeMode(isDarkTheme);

        // 绑定开关状态变化监听
        themeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
            isDarkTheme = isChecked;
            setThemeMode(isDarkTheme);
            saveThemeState(isDarkTheme); // 保存主题状态到 SharedPreferences
        });
    }

    private void setThemeMode(boolean isDark) {
        // 设置全局主题模式
        if (isDark) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            // 深色主题下修改背景和文本颜色
            getWindow().getDecorView().setBackgroundColor(getResources().getColor(R.color.background_theme));
            findViewById(R.id.root_layout).setBackgroundColor(getResources().getColor(R.color.background_theme));
            ((TextView) findViewById(R.id.dev_connect_state)).setTextColor(getResources().getColor(R.color.text_theme));
            // 其他需要调整颜色的组件...
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            getWindow().getDecorView().setBackgroundColor(getResources().getColor(R.color.background_base));
            findViewById(R.id.root_layout).setBackgroundColor(getResources().getColor(R.color.background_base));
            ((TextView) findViewById(R.id.dev_connect_state)).setTextColor(getResources().getColor(R.color.text_primary));
        }
    }

    private void saveThemeState(boolean isDark) {
        getSharedPreferences("ThemePrefs", MODE_PRIVATE)
                .edit()
                .putBoolean("isDarkTheme", isDark)
                .apply();
    }
    private void handleVoiceCommand(String command) {
        switch (command) {
            case "打开灯":
                parlourLightSwitch.setChecked(true);
                break;
            case "关闭灯":
                parlourLightSwitch.setChecked(false);
                break;
            case "打开风扇":
                fan_socket_switch.setChecked(true);
                break;
            case "关闭风扇":
                fan_socket_switch.setChecked(false);
                break;
            // 扩展其他设备指令...
            default:
                speakText("不支持的指令：" + command);
        }
    }

    private void speakText(String text) {
        if (textToSpeech != null) {
            textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);
        }
    }


    private void startVoiceRecognition(View view) {
        // 显示正在录音的提示（例如 Toast）
        Toast.makeText(this, "正在录音...", Toast.LENGTH_SHORT).show();

        // 构建语音识别意图
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.CHINESE);
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "请说出你的指令"); // 设置语音提示文本

        // 启动语音识别（确保语音识别器已正确初始化）
        if (speechRecognizer != null) {
            speechRecognizer.startListening(intent);
        } else {
            Log.e(TAG, "语音识别器未初始化");
        }
    }



    // 修正回调方法参数名（与接口一致）
    @Override
    public void onWeatherFetched(String temperature, String weatherText) {
        NotificationUtils.showWeatherNotification(this, temperature, weatherText);
    }


    private void startDataLoggingTimer() {
        dataLoggerTimer = new Timer();
        dataLoggerTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                logCurrentDeviceUsage();
            }
        }, 0, 60000); // 每分钟执行一次
    }

    private void logCurrentDeviceUsage() {
        runOnUiThread(() -> {
            // 获取当前时间戳
            long currentTime = System.currentTimeMillis();

            // 记录所有正在运行的设备
            for (Map.Entry<String, Long> entry : deviceUsageTime.entrySet()) {
                String deviceId = entry.getKey();
                long startTime = entry.getValue();
                long durationMs = currentTime - startTime;
                double durationHours = durationMs / (1000.0 * 60 * 60);
                double power = devicePowerRatings.getOrDefault(deviceId, 0.0);
                double energy = (power * durationHours) / 1000.0; // kWh
                double emission = CarbonFootprintCalculator.calculateDeviceEmission(power, durationHours);

                // 保存到数据库
                dbHelper.addDeviceUsage(
                        deviceId,
                        startTime,
                        currentTime,
                        energy,
                        emission
                );

                // 更新开始时间为当前时间（为下一分钟记录做准备）
                entry.setValue(currentTime);
            }

            // 更新 UI 显示
            updateCarbonFootprint();
        });
    }

    // 更新碳排放显示
    private void updateCarbonFootprint() {
        runOnUiThread(() -> {
            Map<String, Double> deviceConsumptions = new HashMap<>();
            for (Map.Entry<String, Long> entry : deviceUsageTime.entrySet()) {
                String device = entry.getKey();
                long durationMs = System.currentTimeMillis() - entry.getValue();
                double durationHours = durationMs / (1000.0 * 60 * 60); // 转换为小时
                double power = devicePowerRatings.getOrDefault(device, 0.0);
                deviceConsumptions.put(device, (power * durationHours) / 1000.0); // 转换为 kWh
            }

            double totalEmission = CarbonFootprintCalculator.calculateTotalEmission(deviceConsumptions);
            carbonFootprintView.setText(String.format("碳排放: %.2f kgCO₂", totalEmission));
        });
    }

    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
        String deviceId = "";
        switch (compoundButton.getId()) {
            case R.id.parlour_light_switch:
                deviceId = "light";
                break;
            case R.id.curtain_switch:
                deviceId = "curtain";
                break;
            case R.id.fan_socket_switch:
                deviceId = "fan";
                if (isChecked) {
                    try {
                        mqttBinder.publishMessage("/test/fan1/gear", new Gson().toJson(new IntMessage(currentFanGear)));
                    } catch (MqttException e) {
                        Log.e(TAG, "MQTT publish error", e);
                    }
                }
                break;
            case R.id.air_conditioning_switch:
                deviceId = "ac";
                break;
        }

        // 更新设备使用时间
        if (!deviceId.isEmpty()) {
            if (isChecked) {
                // 设备开启，记录开始时间
                deviceUsageTime.put(deviceId, System.currentTimeMillis());
            } else {
                // 设备关闭，计算使用时长并保存到数据库
                long startTime = deviceUsageTime.getOrDefault(deviceId, 0L);
                if (startTime > 0) {
                    long durationMs = System.currentTimeMillis() - startTime;
                    double durationHours = durationMs / (1000.0 * 60 * 60);
                    double power = devicePowerRatings.getOrDefault(deviceId, 0.0);
                    double energy = (power * durationHours) / 1000.0; // kWh
                    double emission = CarbonFootprintCalculator.calculateDeviceEmission(power, durationHours);

                    // 保存到数据库
                    dbHelper.addDeviceUsage(deviceId, startTime, System.currentTimeMillis(), energy, emission);
                    deviceUsageTime.remove(deviceId);
                }
            }
        }

        // 原有 MQTT 发布代码
        try {
            switch (compoundButton.getId()) {
                case R.id.parlour_light_switch:
                    if (isChecked) {
                        mqttBinder.publishMessage("/test/light1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/light1", new Gson().toJson(new BoolMessage(false)));
                    }
                    break;
                case R.id.curtain_switch:
                    if (isChecked) {
                        mqttBinder.publishMessage("/test/curtain1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/curtain1", new Gson().toJson(new BoolMessage(false)));
                    }
                    break;
                case R.id.fan_socket_switch:
                    if (isChecked) {
                        mqttBinder.publishMessage("/test/fan1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/fan1", new Gson().toJson(new BoolMessage(false)));
                    }
                    break;
                case R.id.air_conditioning_switch:
                    try {
                        float temp = Float.parseFloat(airConditioningValue.getText().toString());
                        String json = new Gson().toJson(new AirConditioningMessage(isChecked, temp));
                        mqttBinder.publishMessage("/test/airConditioning", json);
                    } catch (NumberFormatException e) {
                        Log.e(TAG, "Invalid temperature value", e);
                    }
                    break;
            }
        } catch (MqttException e) {
            Log.e(TAG, "MQTT publish error", e);
        }
    }

    void unSubscribeTopics() {
        try {
            for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                mqttBinder.unSubscribe(entry.getKey());
            }
            subscribeTopics.clear();
        } catch (MqttException e) {
            Log.e(TAG, "Unsubscribe error", e);
        }
    }

    @Override
    public void onConnectSuccess() {
        subscribeTopics();
        connectState.setText("已连接");
    }

    @Override
    public void onConnectError(String error) {
        Log.d(TAG, "onConnectError: " + error);
        connectState.setText("未连接");
        subscribeTopics.clear();
    }

    @Override
    public void onDeliveryComplete() {
        Log.d(TAG, "publish ok");
    }

    @Override
    public void onMqttMessage(String topic, String message) {
        Log.d("onMqttMessage", "topic:" + topic + " message length:" + message.length() + " , message:" + message);
        Gson gson = new Gson();
        switch (subscribeTopics.get(topic)) {
            case 1:
                temperatureValue.setText(String.valueOf(gson.fromJson(message.trim(), FloatMessage.class).value));
                break;
            case 2:
                humidityValue.setText(String.valueOf(gson.fromJson(message.trim(), IntMessage.class).value));
                break;
            case 3:
                pmValue.setText(String.valueOf(gson.fromJson(message.trim(), IntMessage.class).value));
                break;
            case 4:
                gasValue.setText(String.valueOf(gson.fromJson(message.trim(), IntMessage.class).value));
                break;
            case 5:
                String status = gson.fromJson(message.trim(), BoolMessage.class).value ? "开" : "关";
                doorStatus.setText(status);
                break;
        }
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        if (mqttBinder != null && mqttBinder.isConnected()) {
            connectState.setText("已连接");
            subscribeTopics();
        } else {
            connectState.setText("未连接");
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        unSubscribeTopics();
    }

    @Override
    protected void onDestroy() {
        if (dataLoggerTimer != null) {
            dataLoggerTimer.cancel();
            dataLoggerTimer = null;
        }
        if (mqttBinder != null) {
            unbindService(connection);
        }
        super.onDestroy();
    }

    void subscribeTopics() {
        try {
            subscribeTopics.put("/test/temp", 1);
            subscribeTopics.put("/test/hum", 2);
            subscribeTopics.put("/test/pm", 3);
            subscribeTopics.put("/test/gas", 4);
            subscribeTopics.put("/test/door", 5);
            for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                mqttBinder.subscribe(entry.getKey());
            }
        } catch (MqttException e) {
            Log.e(TAG, "Subscribe error", e);
        }
    }
}